<template>
  <md-main>
    <el-collapse-transition>
      <div class="md-body mb20" v-show="showSearch">
        <el-form :model="search" ref="search" size="small" :inline="true">
          <el-form-item label="菜单名称" prop="menuName">
            <el-input v-model="search.menuName" class="w150" placeholder="请输入菜单名称" clearable />
          </el-form-item>
          <el-form-item label="状态" prop="status">
            <el-select v-model="search.status" placeholder="请选择" clearable style="width: 100%">
              <el-option v-for="item in statusList" :key="item.value" :value="item.value" :label="item.label"></el-option>
            </el-select>
          </el-form-item>
          <el-form-item>
            <md-button type="primary" icon="el-icon-search" @click="handleQuery()">搜索</md-button>
            <md-button icon="el-icon-refresh" @click="handleQueryReset()">重置</md-button>
          </el-form-item>
        </el-form>
      </div>
    </el-collapse-transition>

    <div class="md-body md-table">
      <md-toolbar>
        <md-button type="primary" size="small" plain :prems="['system:menu:add']" @click="handleAdd()">新增</md-button>

        <template slot="right">
          <md-button size="mini" icon="el-icon-search" circle @click="showSearch=!showSearch"></md-button>
          <md-button type="primary" size="mini" icon="el-icon-refresh" circle @click="getTableDataList()"></md-button>
        </template>
      </md-toolbar>

      <el-table v-loading="tableLoading" :data="tableData" row-key="menuId" :default-expand-all="false" :tree-props="{children: 'children', hasChildren: 'hasChildren'}">
        <el-table-column prop="menuName" label="菜单名称" :show-overflow-tooltip="true" width="200"></el-table-column>
        <el-table-column prop="icon" label="图标" align="center" width="100">
          <template slot-scope="{ row }">
            <md-icon :name="row.icon" />
          </template>
        </el-table-column>
        <el-table-column prop="orderNum" label="排序" min-width="60"></el-table-column>
        <el-table-column prop="perms" label="权限标识" min-width="200" :show-overflow-tooltip="true">
          <template slot-scope="{ row }">
            {{row.perms || '---'}}
          </template>
        </el-table-column>
        <el-table-column prop="component" label="组件路径" :show-overflow-tooltip="true">
          <template slot-scope="{ row }">
            {{row.component || '---'}}
          </template>
        </el-table-column>
        <el-table-column prop="status" label="状态" min-width="80">
          <template slot-scope="{ $index, row }">
            <el-tag size="mini" :type="statusEnum[row.status].type">{{statusEnum[row.status].label}}</el-tag>
          </template>
        </el-table-column>
        <el-table-column label="创建时间" align="center" prop="createTime" width="170" />
        <el-table-column label="操作" align="center" fixed="right" width="200">
          <template slot-scope="{ row }">
            <md-button size="mini" type="text" icon="el-icon-edit" :prems="['system:menu:edit']" @click="handleUpdate(row)">修改</md-button>
            <md-button size="mini" type="text" icon="el-icon-plus" :prems="['system:menu:add']" @click="handleAdd(row)">新增</md-button>
            <md-button size="mini" type="text" icon="el-icon-delete" :prems="['system:menu:remove']" @click="handleDelete(row)">删除</md-button>
          </template>
        </el-table-column>
      </el-table>
    </div>

    <!-- 添加或修改对话框 -->
    <el-dialog :title="dialog.title" :visible.sync="dialog.open" width="600px" append-to-body :close-on-click-modal="false">
      <el-form ref="form" :model="request" :rules="rules" size="small" label-width="100px" label-position="right">
        <el-row>
          <el-col :span="24">
            <el-form-item label="菜单类型" prop="menuType">
              <el-radio-group v-model="request.menuType">
                <el-radio v-for="item in menuTypeList" :key="item.value" :label="item.value">{{item.label}}</el-radio>
              </el-radio-group>
            </el-form-item>
          </el-col>
        </el-row>

        <el-row>
          <el-col :span="24">
            <el-form-item label="上级" prop="parentId">
              <md-select-tree ref="mdSelectTree" v-model="request.parentId" :defaultExpandAll="false" :data="dialog.menuData" :defaultProps="{label: 'menuName', value: 'menuId'}" placeholder="请选择上级"></md-select-tree>
            </el-form-item>
          </el-col>
        </el-row>

        <!--目录-->
        <template v-if="request.menuType==='M'">
          <el-row>
            <el-col :span="24">
              <el-form-item label="目录图标" prop="icon">
                <md-select-icon v-model="request.icon" placeholder="请选择图标" />
              </el-form-item>
            </el-col>
          </el-row>

          <el-row>
            <el-col :span="12" class="pr5">
              <el-form-item label="目录名称" prop="menuName">
                <el-input v-model="request.menuName" placeholder="请输入目录名称" />
              </el-form-item>
            </el-col>

            <el-col :span="12" class="pl5">
              <el-form-item label="显示排序" prop="orderNum">
                <el-input-number v-model="request.orderNum" controls-position="right" :min="0" />
              </el-form-item>
            </el-col>
          </el-row>

          <el-row>
            <el-col :span="12" class="pr5">
              <el-form-item prop="isFrame">
                <span slot="label">
                  <el-tooltip content="选择是外链则路由地址需要以`http(s)://`开头" placement="top">
                    <i class="el-icon-question"></i>
                  </el-tooltip>
                  是否外链
                </span>
                <el-radio-group v-model="request.isFrame">
                  <el-radio v-for="item in isFrameList" :key="item.value" :label="item.value">{{item.label}}</el-radio>
                </el-radio-group>
              </el-form-item>
            </el-col>

            <el-col :span="12" class="pl5">
              <el-form-item prop="path">
                <span slot="label">
                  <el-tooltip content="访问的路由地址，如：`user`，如外网地址需内链访问则以`http(s)://`开头" placement="top">
                    <i class="el-icon-question"></i>
                  </el-tooltip>
                  路由地址
                </span>
                <el-input v-model="request.path" placeholder="请输入路由地址" />
              </el-form-item>
            </el-col>
          </el-row>

          <el-row>
            <el-col :span="12" class="pr5">
              <el-form-item prop="visible">
                <span slot="label">
                  <el-tooltip content="选择隐藏则路由将不会出现在侧边栏，但仍然可以访问" placement="top">
                    <i class="el-icon-question"></i>
                  </el-tooltip>
                  显示状态
                </span>
                <el-radio-group v-model="request.visible">
                  <el-radio v-for="item in visibleList" :key="item.value" :label="item.value">{{item.label}}</el-radio>
                </el-radio-group>
              </el-form-item>
            </el-col>
            <el-col :span="12" class="pl5">
              <el-form-item prop="status">
                <span slot="label">
                  <el-tooltip content="选择停用则路由将不会出现在侧边栏，也不能被访问" placement="top">
                    <i class="el-icon-question"></i>
                  </el-tooltip>
                  菜单状态
                </span>
                <el-radio-group v-model="request.status">
                  <el-radio v-for="item in statusList" :key="item.value" :label="item.value">{{item.label}}</el-radio>
                </el-radio-group>
              </el-form-item>
            </el-col>
          </el-row>
        </template>

        <!--菜单-->
        <template v-if="request.menuType==='C'">
          <el-row>
            <el-col :span="24">
              <el-form-item label="菜单图标" prop="icon">
                <md-select-icon v-model="request.icon" placeholder="请选择图标" />
              </el-form-item>
            </el-col>
          </el-row>

          <el-row>
            <el-col :span="12" class="pr5">
              <el-form-item label="菜单名称" prop="menuName">
                <el-input v-model="request.menuName" placeholder="请输入菜单名称" />
              </el-form-item>
            </el-col>

            <el-col :span="12" class="pl5">
              <el-form-item label="显示排序" prop="orderNum">
                <el-input-number v-model="request.orderNum" controls-position="right" :min="0" />
              </el-form-item>
            </el-col>
          </el-row>

          <el-row>
            <el-col :span="12" class="pr5">
              <el-form-item prop="isFrame">
                <span slot="label">
                  <el-tooltip content="选择是外链则路由地址需要以`http(s)://`开头" placement="top">
                    <i class="el-icon-question"></i>
                  </el-tooltip>
                  是否外链
                </span>
                <el-radio-group v-model="request.isFrame">
                  <el-radio v-for="item in isFrameList" :key="item.value" :label="item.value">{{item.label}}</el-radio>
                </el-radio-group>
              </el-form-item>
            </el-col>

            <el-col :span="12" class="pl5">
              <el-form-item prop="path">
                <span slot="label">
                  <el-tooltip content="访问的路由地址，如：`user`，如外网地址需内链访问则以`http(s)://`开头" placement="top">
                    <i class="el-icon-question"></i>
                  </el-tooltip>
                  路由地址
                </span>
                <el-input v-model="request.path" placeholder="请输入路由地址" />
              </el-form-item>
            </el-col>
          </el-row>

          <el-row>
            <el-col :span="12" class="pr5">
              <el-form-item prop="component">
                <span slot="label">
                  <el-tooltip content="访问的组件路径，如：`system/user/index`，默认在`views`目录下" placement="top">
                    <i class="el-icon-question"></i>
                  </el-tooltip>
                  组件路径
                </span>
                <el-input v-model="request.component" placeholder="请输入组件路径" />
              </el-form-item>
            </el-col>

            <el-col :span="12" class="pl5">
              <el-form-item prop="perms">
                <el-input v-model="request.perms" placeholder="请输入权限标识" maxlength="100" />
                <span slot="label">
                  <el-tooltip content="控制器中定义的权限字符，如：@PreAuthorize(`@ss.hasPermi('system:user:list')`)" placement="top">
                    <i class="el-icon-question"></i>
                  </el-tooltip>
                  权限字符
                </span>
              </el-form-item>
            </el-col>
          </el-row>

          <el-row>
            <el-col :span="12" class="pr5">
              <el-form-item prop="query">
                <el-input v-model="request.query" placeholder="请输入路由参数" maxlength="255" />
                <span slot="label">
                  <el-tooltip content='访问路由的默认传递参数，如：`{"id": 1, "name": "ry"}`' placement="top">
                    <i class="el-icon-question"></i>
                  </el-tooltip>
                  路由参数
                </span>
              </el-form-item>
            </el-col>
            <el-col :span="12" class="pl5">
              <el-form-item prop="isCache">
                <span slot="label">
                  <el-tooltip content="选择是则会被`keep-alive`缓存，需要匹配组件的`name`和地址保持一致" placement="top">
                    <i class="el-icon-question"></i>
                  </el-tooltip>
                  是否缓存
                </span>
                <el-radio-group v-model="request.isCache">
                  <el-radio v-for="item in isCacheList" :key="item.value" :label="item.value">{{item.label}}</el-radio>
                </el-radio-group>
              </el-form-item>
            </el-col>
          </el-row>

          <el-row>
            <el-col :span="12" class="pr5">
              <el-form-item prop="visible">
                <span slot="label">
                  <el-tooltip content="选择隐藏则路由将不会出现在侧边栏，但仍然可以访问" placement="top">
                    <i class="el-icon-question"></i>
                  </el-tooltip>
                  显示状态
                </span>
                <el-radio-group v-model="request.visible">
                  <el-radio v-for="item in visibleList" :key="item.value" :label="item.value">{{item.label}}</el-radio>
                </el-radio-group>
              </el-form-item>
            </el-col>
            <el-col :span="12" class="pl5">
              <el-form-item prop="status">
                <span slot="label">
                  <el-tooltip content="选择停用则路由将不会出现在侧边栏，也不能被访问" placement="top">
                    <i class="el-icon-question"></i>
                  </el-tooltip>
                  菜单状态
                </span>
                <el-radio-group v-model="request.status">
                  <el-radio v-for="item in statusList" :key="item.value" :label="item.value">{{item.label}}</el-radio>
                </el-radio-group>
              </el-form-item>
            </el-col>
          </el-row>
        </template>

        <!--按钮-->
        <template v-if="request.menuType==='F'">
          <el-row>
            <el-col :span="12" class="pr5">
              <el-form-item label="按钮名称" prop="menuName">
                <el-input v-model="request.menuName" placeholder="请输入按钮名称" />
              </el-form-item>
            </el-col>

            <el-col :span="12" class="pl5">
              <el-form-item label="显示排序" prop="orderNum">
                <el-input-number v-model="request.orderNum" controls-position="right" :min="0" />
              </el-form-item>
            </el-col>
          </el-row>

          <el-row>
            <el-col :span="24">
              <el-form-item prop="perms">
                <el-input v-model="request.perms" placeholder="请输入权限标识" maxlength="100" />
                <span slot="label">
                  <el-tooltip content="控制器中定义的权限字符，如：@PreAuthorize(`@ss.hasPermi('system:user:list')`)" placement="top">
                    <i class="el-icon-question"></i>
                  </el-tooltip>
                  权限字符
                </span>
              </el-form-item>
            </el-col>
          </el-row>
        </template>
      </el-form>
      <div slot="footer" class="dialog-footer">
        <el-button type="primary" size="small" @click="handleSubmit">确 定</el-button>
        <el-button size="small" @click="handleCancel">取 消</el-button>
      </div>
    </el-dialog>
  </md-main>
</template>

<script>
import { insertMenu, updateMenu, delMenu, treeListMenu, getMenu } from '@/api/system/menu.service.js'
export default {
  name: 'MdSystemMenuComponent',
  data () {
    return {
      isFrameEnum, isFrameList, isCacheEnum, isCacheList, menuTypeEnum, menuTypeList, visibleEnum, visibleList, statusEnum, statusList,
      // 显示隐藏查询条件
      showSearch: true,
      // 查询参数
      search: searchParams,
      // 列表加载
      tableLoading: false,
      // 列表数据
      tableData: [],
      // 添加/编辑请求参数
      request: requestParams,
      rules: rules,
      // 添加/编辑弹窗
      dialog: {
        title: '添加菜单',
        open: false,
        menuData: []
      }
    }
  },
  mounted () {
    this.getTableDataList()
  },
  methods: {
    /** 获取菜单数据 */
    async getTableDataList () {
      this.tableLoading = true

      try {
        const res = await treeListMenu(this.search)

        this.tableData = []
        this.tableData = res.data
        this.dialog.menuData = []
        this.dialog.menuData = [{ menuId: 0, menuName: '一级菜单', parentId: 0, children: res.data }]
      } catch (error) {
        console.log(error)
      }

      this.tableLoading = false
    },
    /** 搜索 */
    handleQuery () {
      this.search.pageNum = 1

      this.getTableDataList()
    },
    /** 重置搜索 */
    handleQueryReset () {
      this.search = { ...searchParams }

      this.getTableDataList()
    },
    // 重置表单数据
    handleReset () {
      this.request = { ...requestParams }
      if (this.$refs.form) {
        this.$refs.form.resetFields();
      }
    },
    /** 删除 */
    async handleDelete (row) {
      try {
        await this.$confirm(`是否确认删除名称为 ${row.menuName} 的数据项？`)

        await delMenu(row.menuId)

        this.$message.success('删除成功')

        this.getTableDataList()
      } catch (error) {
        console.log(error)
      }
    },
    /** 添加 */
    async handleAdd (row) {
      try {
        this.handleReset()

        this.dialog.title = '添加菜单'

        this.request = { ...requestParams }

        this.request.parentId = row ? row.menuId : 0

        this.dialog.open = true

        this.$nextTick(() => {
          const treeSelect = this.$refs.mdSelectTree

          treeSelect.$refs.mdSelectTree.setCheckedKeys([])

          treeSelect.$refs.mdSelectTree.setCheckedKeys([this.request.parentId])
        })

      } catch (error) {
        console.log(error)
      }
    },
    /** 更新 */
    async handleUpdate (row) {
      try {
        this.handleReset()

        this.dialog.title = '修改菜单'

        const res = await getMenu(row.menuId)

        this.request = res.data

        this.dialog.open = true

        this.$nextTick(() => {
          const treeSelect = this.$refs.mdSelectTree

          treeSelect.$refs.mdSelectTree.setCheckedKeys([])

          treeSelect.$refs.mdSelectTree.setCheckedKeys([this.request.parentId])
        })

      } catch (error) {
        console.log(error)
      }
    },
    /** 保存 */
    handleSubmit () {
      this.$refs.form.validate(async valid => {
        if (!valid) {
          return
        }

        try {
          const params = Object.assign({}, { ...this.request })

          await (params.menuId === undefined ? insertMenu : updateMenu)(params)

          this.$message.success(params.menuId === undefined ? '添加成功' : '修改成功')

          this.dialog.open = false;

          this.getTableDataList()
        } catch (error) {
          console.log(error)
        }
      })
    },
    handleCancel () {
      this.dialog.open = false

      this.handleReset()
    }
  }
}
const searchParams = {
  menuName: undefined,
  parentId: undefined,
  isFrame: undefined,
  isCache: undefined,
  menuType: undefined,
  visible: undefined,
  status: undefined,
  createBy: undefined,
  updateBy: undefined,
  beginDate: undefined,
  endDate: undefined,
  orderBy: 'order_num',
  isDesc: false
}

const requestParams = {
  menuId: undefined,
  menuName: undefined,
  parentId: 0,
  orderNum: 100,
  path: undefined,
  component: undefined,
  routeParams: undefined,
  isFrame: 0,
  isCache: 0,
  menuType: 'M',
  visible: '0',
  status: '0',
  perms: undefined,
  icon: undefined,
  remark: undefined,
}

const rules = {
  menuName: [{ required: true, message: '请输入菜单名称', trigger: 'blur' }],
  path: [{ required: true, message: '请输入路由地址', trigger: 'blur' }]
}

const isFrameEnum = {
  0: { label: '是', type: 'primary' },
  1: { label: '否', type: 'warning' }
}
const isFrameList = Object.keys(isFrameEnum).map(m => { return { value: parseInt(m), label: isFrameEnum[m].label } })

const isCacheEnum = {
  0: { label: '缓存', type: 'primary' },
  1: { label: '不缓存', type: 'warning' }
}
const isCacheList = Object.keys(isCacheEnum).map(m => { return { value: parseInt(m), label: isCacheEnum[m].label } })

const menuTypeEnum = {
  'M': { label: '目录', type: 'primary' },
  'C': { label: '菜单', type: 'success' },
  'F': { label: '按钮', type: 'primary' }
}
const menuTypeList = Object.keys(menuTypeEnum).map(m => { return { value: m, label: menuTypeEnum[m].label } })

const visibleEnum = {
  '0': { label: '显示', type: 'primary' },
  '1': { label: '隐藏', type: 'warning' }
}
const visibleList = Object.keys(visibleEnum).map(m => { return { value: m, label: visibleEnum[m].label } })

const statusEnum = {
  '0': { label: '正常', type: 'primary' },
  '1': { label: '停用', type: 'warning' }
}
const statusList = Object.keys(statusEnum).map(m => { return { value: m, label: statusEnum[m].label } })
</script>